﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Windows.Forms;
using System.Web;
using System.Globalization;
using Microsoft.Win32;


namespace MediaPortal.GUI.iPlayer
{
    public class iPlayerTranslator
    {
        public List<TVProgram> theBBCPrograms;
        public string BBC_UID;
        private string userAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)";
        public Boolean isLoaded;
        string iPlayerFile = "iPlayer3.htm";
        public int added, removed, total,processed;
        Preferences prefs;
        public int pageCount;
        private string provider = "BBC";

        public iPlayerTranslator()
        {
            theBBCPrograms = new List<TVProgram>();
            isLoaded = false;

        }
        public iPlayerTranslator(Preferences _prefs)
        {
            init(_prefs);
        }
        public void init(Preferences _prefs){
            prefs = _prefs;
            theBBCPrograms = new List<TVProgram>();
            isLoaded = false;
            pageCount = 0;
            processed = 0;

        }
        public void setPrefs(Preferences _prefs)
        {
            prefs = _prefs;
        }
        private string getWebPage(string url)
        {
            pageCount++;
            string result = "";
            try
            {
                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(url);
                myRequest.UserAgent = userAgent;
                myRequest.Method = "GET";
                CookieContainer c1 = new CookieContainer();
                myRequest.CookieContainer = c1;
                HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
                StreamReader sr = new StreamReader(myResponse.GetResponseStream(), System.Text.Encoding.UTF8);
                result = sr.ReadToEnd();
                sr.Close();
                if (BBC_UID == null)
                {

                    CookieCollection cc1 = c1.GetCookies(new Uri("http://www.bbc.co.uk/"));
                    Cookie BBCCookie = cc1["BBC-UID"];
                    BBC_UID = BBCCookie.Value.Substring(0, 64);
                }
            }
            catch (Exception e) { }
            return result;
        }

        public TVProgramList loadDatabaseChannel(TVProgramList listIn, string channel)
        {
            provider = "BBC";
            theBBCPrograms = new List<TVProgram>();
            parseXMLStream(channel);

            Boolean existsAlready = false;
            foreach (TVProgram p1 in theBBCPrograms)
            {
                existsAlready = false;
                foreach (TVProgram innerP in listIn.thePrograms)
                {
                    if (innerP.ProgramId == p1.ProgramId)
                    {
                        existsAlready = true;
                        break;
                    }
                }
                if (!existsAlready)
                {

                    listIn.Add(p1);
                }
            }

            //isLoaded = true;
            return listIn;
        }


        public TVProgramList loadDatabase(TVProgramList listIn, string multiThread)
        {
            isLoaded = false;

            provider = "BBC";
            pageCount = 0;
            processed = 0;
            theBBCPrograms = new List<TVProgram>();
            if (multiThread == "1")
            {
                string channel = "bbc_one";
                Thread bbc_one_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_one_thread.Start(channel);

                channel = "bbc_two";
                Thread bbc_two_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_two_thread.Start(channel);

                channel = "bbc_three";
                Thread bbc_three_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_three_thread.Start(channel);

                channel = "bbc_four";
                Thread bbc_four_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_four_thread.Start(channel);

                channel = "cbbc";
                Thread cbbc_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                cbbc_thread.Start(channel);

                channel = "cbeebies";
                Thread cbeebies_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                cbeebies_thread.Start(channel);

                channel = "bbc_news24";
                Thread bbc_news24_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_news24_thread.Start(channel);

                Thread bbc_alba_thread = null;
                if (prefs.bbc_alba == "1")
                {
                    channel = "bbc_alba";
                    bbc_alba_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                    bbc_alba_thread.Start(channel);
                }

                Thread bbc_scotland_thread = null;
                if (prefs.bbc_scotland == "1")
                {

                    channel = "categories/scotland";
                    bbc_scotland_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                    bbc_scotland_thread.Start(channel);
                }

                Thread bbc_northern_ireland_thread = null;
                if (prefs.bbc_ireland == "1")
                {
                    channel = "categories/northern_ireland";
                    bbc_northern_ireland_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                    bbc_northern_ireland_thread.Start(channel);
                }

                Thread bbc_wales_thread = null;
                if (prefs.bbc_wales == "1")
                {
                    channel = "categories/wales";
                    bbc_wales_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                    bbc_wales_thread.Start(channel);
                }

                bbc_one_thread.Join();
                bbc_two_thread.Join();
                bbc_three_thread.Join();
                bbc_four_thread.Join();
                cbbc_thread.Join();
                cbeebies_thread.Join();
                bbc_news24_thread.Join();
                if (prefs.bbc_alba == "1")
                {
                    bbc_alba_thread.Join();
                }

                if (prefs.bbc_scotland == "1")
                {
                    bbc_scotland_thread.Join();
                }
                if (prefs.bbc_ireland == "1")
                {
                    bbc_northern_ireland_thread.Join();
                }
                if (prefs.bbc_wales == "1")
                {
                    bbc_wales_thread.Join();
                }
            }
            else
            {
                parseXMLStream("bbc_one");
                parseXMLStream("bbc_two");
                parseXMLStream("bbc_three");
                parseXMLStream("bbc_four");
                parseXMLStream("cbbc");
                parseXMLStream("cbeebies");
                parseXMLStream("bbc_news24");
                if (prefs.bbc_alba == "1")
                {
                    parseXMLStream("bbc_alba");
                }
                if (prefs.bbc_scotland == "1")
                {
                    parseXMLStream("categories/scotland");
                }
                if (prefs.bbc_ireland == "1")
                {
                    parseXMLStream("categories/northern_ireland");
                }
                if (prefs.bbc_wales == "1")
                {
                    parseXMLStream("categories/wales");
                }
            }

            int beginCount = listIn.thePrograms.Count;
            listIn.thePrograms.RemoveAll(delegate(TVProgram p1) { return (p1.ProgramProvider == provider) && (theBBCPrograms.Exists(delegate(TVProgram pInner) { return (pInner.ProgramId == p1.ProgramId); }) == false); });
            removed = beginCount - listIn.thePrograms.Count;


            Boolean existsAlready = false;
            added = 0;
            foreach (TVProgram p1 in theBBCPrograms)
            {
                existsAlready = false;
                foreach (TVProgram innerP in listIn.thePrograms)
                {
                    if (innerP.ProgramId == p1.ProgramId)
                    {
                        existsAlready = true;
                        break;
                    }
                }
                if (!existsAlready)
                {

                    listIn.Add(p1);
                    added++;
                }
            }

            total = 0;
            listIn.thePrograms.ForEach(delegate(TVProgram p1) { if (p1.ProgramProvider == provider) { total++; } });
            isLoaded = true;
            return listIn;


        }

        public TVProgramList loadRadioDatabase(TVProgramList listIn, string multiThread)
        {
            isLoaded = false;
            provider = "BBCRADIO";
            pageCount = 0;
            processed = 0;
            theBBCPrograms = new List<TVProgram>();
            if (multiThread == "1")
            {
                string channel = "bbc_radio_one";
                Thread bbc_one_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_one_thread.Start(channel);

                channel = "bbc_1xtra";
                Thread bbc_1xtra_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_1xtra_thread.Start(channel);

                channel = "bbc_radio_two";
                Thread bbc_two_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_two_thread.Start(channel);

                channel = "bbc_radio_three";
                Thread bbc_three_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_three_thread.Start(channel);

                bbc_one_thread.Join();
                bbc_1xtra_thread.Join();
                bbc_two_thread.Join();
                bbc_three_thread.Join();


                channel = "bbc_radio_four";
                Thread bbc_four_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_four_thread.Start(channel);

                channel = "bbc_radio_five_live";
                Thread bbc_radio_five_live_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_five_live_thread.Start(channel);

                channel = "bbc_radio_five_live_sports_extra";
                Thread bbc_radio_five_live_sports_extra_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_five_live_sports_extra_thread.Start(channel);

                channel = "bbc_6music";
                Thread bbc_6music_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_6music_thread.Start(channel);

                bbc_four_thread.Join();
                bbc_radio_five_live_thread.Join();
                bbc_radio_five_live_sports_extra_thread.Join();
                bbc_6music_thread.Join();

                channel = "bbc_7";
                Thread bbc_7_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_7_thread.Start(channel);

                channel = "bbc_asian_network";
                Thread bbc_asian_network_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_asian_network_thread.Start(channel);

                channel = "bbc_world_service";
                Thread bbc_world_service_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_world_service_thread.Start(channel);

                channel = "bbc_radio_scotland";
                Thread bbc_radio_scotland_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_scotland_thread.Start(channel);

                bbc_7_thread.Join();
                bbc_asian_network_thread.Join();
                bbc_world_service_thread.Join();
                bbc_radio_scotland_thread.Join();

                channel = "bbc_radio_foyle";
                Thread bbc_radio_foyle_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_foyle_thread.Start(channel);

                channel = "bbc_radio_nan_gaidheal";
                Thread bbc_radio_nan_gaidheal_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_nan_gaidheal_thread.Start(channel);

                channel = "bbc_radio_ulster";
                Thread bbc_radio_ulster_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_ulster_thread.Start(channel);

                channel = "bbc_radio_wales";
                Thread bbc_radio_wales_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_wales_thread.Start(channel);

                channel = "bbc_radio_cymru";
                Thread bbc_radio_cymru_thread = new Thread(new ParameterizedThreadStart(parseXMLStream));
                bbc_radio_cymru_thread.Start(channel);

                bbc_radio_foyle_thread.Join();
                bbc_radio_nan_gaidheal_thread.Join();
                bbc_radio_ulster_thread.Join();
                bbc_radio_wales_thread.Join();
                bbc_radio_cymru_thread.Join();



            }
            else
            {
                parseXMLStream("bbc_radio_one");
                parseXMLStream("bbc_1xtra_one");
                parseXMLStream("bbc_radio_two");
                parseXMLStream("bbc_radio_three");
                parseXMLStream("bbc_radio_four");
                parseXMLStream("bbc_radio_five_live");
                parseXMLStream("bbc_radio_five_live_sports_extra");
                parseXMLStream("bbc_6music");
                parseXMLStream("bbc_7");
                parseXMLStream("bbc_asian_network");
                parseXMLStream("bbc_world_service");
                parseXMLStream("bbc_radio_scotland");
                parseXMLStream("bbc_radio_foyle_thread");
                parseXMLStream("bbc_radio_nan_gaidheal");
                parseXMLStream("bbc_radio_ulster");
                parseXMLStream("bbc_radio_wales");
                parseXMLStream("bbc_radio_cymru");

            }

            int beginCount = listIn.thePrograms.Count;
            listIn.thePrograms.RemoveAll(delegate(TVProgram p1) { return (p1.ProgramProvider == provider) && (theBBCPrograms.Exists(delegate(TVProgram pInner) { return (pInner.ProgramId == p1.ProgramId); }) == false); });
            removed = beginCount - listIn.thePrograms.Count;


            Boolean existsAlready = false;
            added = 0;
            foreach (TVProgram p1 in theBBCPrograms)
            {
                existsAlready = false;
                foreach (TVProgram innerP in listIn.thePrograms)
                {
                    if ((innerP.ProgramId == p1.ProgramId)&&(innerP.ProgramProvider==p1.ProgramProvider))
                    {
                        existsAlready = true;
                        break;
                    }
                }
                if (!existsAlready)
                {

                    listIn.Add(p1);
                    added++;
                }
            }

            total = 0;
            listIn.thePrograms.ForEach(delegate(TVProgram p1) { if (p1.ProgramProvider == provider) { total++; } });
            isLoaded = true;
            return listIn;


        }


        public void parseXMLStream(object _channel)
        {
            string channel = (string)_channel;
            string feed = "http://feeds.bbc.co.uk/iplayer/" + channel + "/list";
            if (channel.StartsWith("categories"))
            {
                channel = channel.Substring(11);
            }
            string result = getWebPage(feed);
            int start = 0;
            int lastStart = 0;
            string searchStr = "<entry>";
            int itemStart, itemEnd;
            string tag;
            string id, episodeImage, title, episodeTitle, summary, programLink,programDate;
            DateTime lastBroadcast;
            while (start < result.Length)
            {
                start = result.IndexOf(searchStr, lastStart);
                if (start > 0)
                {
                    processed++;
                    start += searchStr.Length;
                    itemEnd = start;
                    tag = "PIPS:";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("<", itemStart);
                        id = result.Substring(itemStart, itemEnd - itemStart);
                    }
                    else
                    {
                        id = "";
                    }

                    tag = "<media:thumbnail url=\"";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("\"", itemStart);
                        episodeImage = result.Substring(itemStart, itemEnd - itemStart);
                        if (!episodeImage.StartsWith("http"))
                        {
                            episodeImage = "http://www.bbc.com" + episodeImage;
                        }
                    }
                    else
                    {
                        episodeImage = "";
                    }

                    tag = "title";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        tag = ">";
                        itemStart = result.IndexOf(tag, itemStart) + tag.Length;
                        itemEnd = Math.Min(result.IndexOf(":", itemStart), result.IndexOf("<", itemStart));
                        title = prefs.cleanString(result.Substring(itemStart, itemEnd - itemStart));
                    }
                    else
                    {
                        title = "";
                    }

                    tag = "link rel=\"self\"";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        tag = "title=\"";
                        itemStart = result.IndexOf(tag, itemStart) + tag.Length;
                        itemEnd = result.IndexOf("\"", itemStart);
                        episodeTitle = prefs.cleanString(result.Substring(itemStart, itemEnd - itemStart));
                    }
                    else
                    {
                        episodeTitle = "";
                    }

                    tag = "<content type=\"html\">";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        tag = "&lt;p&gt;";
                        itemStart = result.IndexOf(tag, itemStart) + tag.Length;
                        tag = "&lt;p&gt;";
                        itemStart = result.IndexOf(tag, itemStart) + tag.Length;
                        itemEnd = result.IndexOf("&lt;/p&gt;", itemStart);
                        summary = prefs.cleanString(result.Substring(itemStart, itemEnd - itemStart).Trim());
                    }
                    else
                    {
                        summary = "";
                    }

                    programLink = prefs.installedDirectory + iPlayerFile + "?id=" + id
    + "&title=" + System.Web.HttpUtility.UrlPathEncode(title)
    + "&episode=" + System.Web.HttpUtility.UrlPathEncode(summary)
    + "&BBC_UID=" + BBC_UID;

                    lastBroadcast = DateTime.Now;
                    try
                    {
                        tag = "<updated>";
                        itemStart = result.IndexOf(tag, start);
                        if (itemStart > 0)
                        {
                            itemStart += tag.Length;
                            itemEnd = result.IndexOf("<", itemStart);
                            programDate = result.Substring(itemStart, itemEnd - itemStart);
                            lastBroadcast = DateTime.Parse(programDate, CultureInfo.CurrentCulture);
                        }
                    }
                    catch (Exception e)
                    {
                    }
                    string channelLogo = "http://www.bbc.co.uk/iplayer/img/nav/tv/" + channel + ".gif";
                    if (provider == "BBCRADIO")
                    {
                        channelLogo = "http://www.bbc.co.uk/iplayer/img/nav/radio/" + channel + ".gif";
                    }

                    if ((channel == "scotland") || (channel == "wales") || (channel == "ireland"))
                    {
                        channelLogo = "http://www.bbc.co.uk/iplayer/img/nav/tv/bbc_one.gif";
                    }

                    TVProgram p1 = new TVProgram(title, programLink, episodeTitle, episodeImage, summary, provider, "", lastBroadcast, channel, channelLogo, id);

                    theBBCPrograms.Add(p1);
                    lastStart = itemEnd;
                }
                else
                {
                    break;
                }
            }
        }

    
 /*       public void parseBaseBetaPage(object _channel)
        {
            string channel = (string)_channel;
            int i = 1;

            string result = "class=\"next";
            string result2;
            int start,end;
            while (result.Contains("class=\"next"))
            {
                result=getWebPage("http://www.bbc.co.uk/iplayer/tv/"+channel+"?page="+i++);
                start=result.IndexOf("listview");
                if (start < 0)
                {
                    start = 0;
                }
                end = result.IndexOf("bip-rss",start);
                if (end < 0)
                {
                    end = result.Length;
                }
                if (start > 0)
                {
                    result2 = result.Substring(start, (end - start));
                    parseBetaPage(result2, channel);
                }
            }
        }


                public void parseBetaPage(string result,string channel)
        {
            int start = 0;
            int lastStart = 0;
            string searchStr = "class=\"episode";
            int itemStart, itemEnd;
            string tag;
            string id, episodeImage, title, episodeTitle, summary, programLink;
            while (start < result.Length)
            {
                start = result.IndexOf(searchStr, lastStart);
                if (start > 0)
                {
                    start += searchStr.Length;
                    itemEnd = start;
                    tag = "/episode/";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("\"", itemStart);
                        id = result.Substring(itemStart, itemEnd - itemStart);
                    }
                    else
                    {
                        id = "";
                    }

                    tag = "<img src=\"";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("\"", itemStart);
                        episodeImage = result.Substring(itemStart, itemEnd - itemStart);
                        if (!episodeImage.StartsWith("http"))
                        {
                            episodeImage = "http://www.bbc.com" + episodeImage;
                        }
                    } else {
                        episodeImage = "";
                    }

                    tag = "class=\"se-title\">";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("<", itemStart);
                        title = result.Substring(itemStart, itemEnd - itemStart);
                    }
                    else
                    {
                        title = "";
                    }

                    tag = "class=\"ep-title\">";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("<", itemStart);
                        episodeTitle = result.Substring(itemStart, itemEnd - itemStart);
                    }
                    else
                    {
                        episodeTitle = "";
                    }

                    tag = "class=\"description\"><p>";
                    itemStart = result.IndexOf(tag, start);
                    if (itemStart > 0)
                    {
                        itemStart += tag.Length;
                        itemEnd = result.IndexOf("<", itemStart);
                        summary = result.Substring(itemStart, itemEnd - itemStart);
                    }
                    else
                    {
                        summary = "";
                    }

                    programLink = workingDir + iPlayerFile+"?id=" + id
    + "&title=" + System.Web.HttpUtility.UrlPathEncode(title)
    + "&episode=" + System.Web.HttpUtility.UrlPathEncode(summary)
    + "&BBC_UID=" + BBC_UID;


                    TVProgram p1 = new TVProgram(title, programLink, episodeTitle, episodeImage, summary, "BBC", "", DateTime.Now, channel, "http://www.bbc.co.uk/iplayer/framework/img/ch/" + channel + ".gif", id);

                    thePrograms.Add(p1);
                    lastStart = itemEnd;
                }
                else
                {
                    break;
                }
            }
        }
    */
    }

    /*public class pageId
    {
        string _pageId;
        public pageId(string pageIdIn)
        {
            _pageId = pageIdIn;
        }
    }*/

}
